package com.crm.business.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CreateCache;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.crm.business.admin.mapper.AdminDeptMapper;
import com.crm.business.admin.service.AdminService;
import com.crm.business.admin.service.IAdminDeptService;
import com.crm.business.admin.service.IAdminUserService;
import com.crm.business.crm.service.BillCrmOrderPoolService;
import com.crm.business.crm.service.IBillCrmStudentPoolService;
import com.crm.common.admin.common.AdminCodeEnum;
import com.crm.common.admin.entity.BO.AdminDeptBO;
import com.crm.common.admin.entity.BO.AdminDeptQueryBO;
import com.crm.common.admin.entity.BO.DeptVO;
import com.crm.common.admin.entity.PO.AdminDept;
import com.crm.common.admin.entity.VO.AdminDeptVO;
import com.crm.common.ka.core.common.BaseStatusEnum;
import com.crm.common.ka.core.common.Const;
import com.crm.common.ka.core.common.SystemCodeEnum;
import com.crm.common.ka.core.entity.UserInfo;
import com.crm.common.ka.core.exception.CrmException;
import com.crm.common.ka.core.feign.admin.entity.SimpleDept;
import com.crm.business.servlet.ApplicationContextHolder;
import com.crm.business.servlet.BaseServiceImpl;
import com.crm.common.ka.core.utils.RecursionUtil;
import com.crm.business.utils.UserUtil;
import com.crm.common.utils.StringUtils;
import com.crm.common.utils.spring.SpringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author zhangzhiwei
 * @since 2020-04-27
 */
@Service
public class AdminDeptServiceImpl extends BaseServiceImpl<AdminDeptMapper, AdminDept> implements IAdminDeptService {

    @Autowired
    private IAdminUserService adminUserService;

    @Autowired
    private BillCrmOrderPoolService crmOrderPoolService;

    @Autowired
    private IBillCrmStudentPoolService crmStudentPoolService;

    @CreateCache(name = Const.ADMIN_DEPT_NAME_CACHE_NAME, expire = 3, timeUnit = TimeUnit.DAYS)
    private Cache<Integer, String> deptCache;

    /**
     * 查询部门树
     *
     * @param queryBO 上级ID
     * @return data
     */
    @Override
    public List<AdminDeptVO> queryDeptTree(AdminDeptQueryBO queryBO) {
        if (queryBO.getId() == null) {
            queryBO.setId(0);
        }
        List<AdminDept> adminDeptList = listNew();

        if ("tree".equals(queryBO.getType())) {
            return RecursionUtil.getChildListTree(adminDeptList, "pid", queryBO.getId(), "deptId", "children", AdminDeptVO.class);
        }
        if ("new_tree".equals(queryBO.getType())) {
            if(!UserUtil.isAdmin()) {
                UserInfo userInfo = UserUtil.getUser();
                if (Optional.ofNullable(userInfo).isPresent() && Optional.ofNullable(userInfo.getDeptId()).isPresent()) {
                    //queryBO.setId(userInfo.getDeptId());
                    Integer parentId = userInfo.getDeptId();
                    Integer pid = getBaseMapper().queryPidByDept(userInfo.getDeptId());
                    queryBO.setId(pid);
                }
            }
            return RecursionUtil.getChildListTree(adminDeptList, "pid", queryBO.getId(), "deptId", "children", AdminDeptVO.class);
        }
        if ("update".equals(queryBO.getType())) {
            List<Integer> ids = RecursionUtil.getChildList(adminDeptList, "pid", queryBO.getId(), "deptId", "deptId");
            adminDeptList.removeIf(dept -> ids.contains(dept.getDeptId()));
        }


        if("child_tree".equals(queryBO.getType())){
            AdminDeptVO currentDept = new AdminDeptVO();
            currentDept.setDeptId(queryBO.getId());
            currentDept.setId(queryBO.getId());
            currentDept.setValue(queryBO.getId());
            currentDept.setName(SpringUtils.getBean(AdminService.class).queryDeptName(queryBO.getId()));
            currentDept.setLabel(SpringUtils.getBean(AdminService.class).queryDeptName(queryBO.getId()));
            currentDept.setChildren(RecursionUtil.getChildListTree(adminDeptList, "pid", queryBO.getId(), "deptId", "children", AdminDeptVO.class));
            List<AdminDeptVO> adminDeptVOList = new ArrayList<>();
            adminDeptVOList.add(currentDept);
            return adminDeptVOList;

        }

        return adminDeptList.stream().map(obj -> BeanUtil.copyProperties(obj, AdminDeptVO.class)).collect(Collectors.toList());
    }

    /**
     * 查询部门下属部门
     *
     * @param parentId 上级ID
     * @return data
     */
    @Override
    public List<Integer> queryChildDept(Integer parentId) {
        return RecursionUtil.getChildList(list(), "pid", parentId, "deptId", "deptId");
    }

    /**
     * 新增部门
     *
     * @param adminDeptBO 部门信息
     */
    @Override
    public void addDept(AdminDeptBO adminDeptBO) {
        //pid为0的部门只能存在一个
        if (BaseStatusEnum.CLOSE.getStatus().equals(adminDeptBO.getPid())) {
            throw new CrmException(SystemCodeEnum.SYSTEM_NO_VALID);
        }
        save(BeanUtil.copyProperties(adminDeptBO, AdminDept.class));
    }

    /**
     * 修改部门
     *
     * @param adminDeptBO 部门信息
     */
    @Override
    public void setDept(AdminDeptBO adminDeptBO) {
        List<Integer> deptIdList = queryChildDept(adminDeptBO.getDeptId());
        deptIdList.add(adminDeptBO.getDeptId());
        if (deptIdList.contains(adminDeptBO.getPid())) {
            throw new CrmException(AdminCodeEnum.ADMIN_PARENT_DEPT_ERROR);
        }
        AdminDept adminDept = getById(adminDeptBO.getDeptId());
        //pid为0的部门只能存在一个
        if ((!adminDept.getPid().equals(0)) && adminDeptBO.getPid().equals(0)) {
            throw new CrmException(SystemCodeEnum.SYSTEM_NO_VALID);
        }
        adminDept.setName(adminDeptBO.getName());
        adminDept.setPid(adminDeptBO.getPid());
        updateById(adminDept);
        deptCache.remove(adminDeptBO.getDeptId());
    }

    /**
     * 删除部门
     *
     * @param deptId 部门ID
     */
    @Override
    public void deleteDept(Integer deptId) {
        Integer userCount = adminUserService.query().eq("dept_id", deptId).count();
        if (userCount > 0) {
            throw new CrmException(AdminCodeEnum.ADMIN_DEPT_REMOVE_EXIST_USER_ERROR);
        }
        Integer deptCount = query().eq("pid", deptId).count();
        if (deptCount > 0) {
            throw new CrmException(AdminCodeEnum.ADMIN_DEPT_REMOVE_EXIST_DEPT_ERROR);
        }

        // 校验部门是否绑定账单池及VIP学员池
//        QueryWrapper<BillCrmStudentPool> queryWrapper = new QueryWrapper<BillCrmStudentPool>();
//        queryWrapper.eq("status", 1);
//        BillCrmStudentPool studentPool = crmStudentPoolService.getBaseMapper().selectOne(queryWrapper);
//        List<String> deptIdsForStudentPool = Arrays.asList(studentPool.getMemberDeptId().split(","));
//
//        if(deptIdsForStudentPool.contains(String.valueOf(deptId))){
//            throw new CrmException(AdminCodeEnum.ADMIN_DEPT_BIND_STUDENT_POOL);
//        }
//
//        QueryWrapper<BillCrmOrderPool> orderPoolQueryWrapper = new QueryWrapper<>();
//        orderPoolQueryWrapper.eq("status", 1);
//        BillCrmOrderPool orderPool = crmOrderPoolService.getBaseMapper().selectOne(orderPoolQueryWrapper);
//        List<String> deptIdsForOrderPool = Arrays.asList(orderPool.getMemberDeptId().split(","));
//
//        if(deptIdsForOrderPool.contains(String.valueOf(deptId))){
//            throw new CrmException(AdminCodeEnum.ADMIN_DEPT_BIND_ORDER_POOL);
//        }

        removeById(deptId);
        deptCache.remove(deptId);
    }

    /**
     * 根据部门ID获取部门名称
     *
     * @param deptId 部门ID
     * @return data
     */
    @Override
    public String getNameByDeptId(Integer deptId) {
        if (deptCache.get(deptId) != null){
            return deptCache.get(deptId);
        }
        AdminDept adminDept = query().select("name").eq("dept_id", deptId).one();
        if (adminDept == null) {
            return "";
        }
        deptCache.put(deptId, adminDept.getName());
        return adminDept.getName();
    }

    /**
     * 根据ids查询用户信息
     *
     * @param ids id列表
     * @return data
     */
    @Override
    public List<SimpleDept> queryDeptByIds(List<Integer> ids) {
        if (ids.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AdminDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(AdminDept::getDeptId, AdminDept::getName).in(AdminDept::getDeptId, ids);
        return list(queryWrapper).stream().map(obj -> {
            SimpleDept simpleDept = new SimpleDept();
            simpleDept.setId(obj.getDeptId());
            simpleDept.setName(obj.getName());
            return simpleDept;
        }).collect(Collectors.toList());
    }

    @Override
    public List<DeptVO> queryDeptUserList() {
        return getBaseMapper().queryDeptUserList();
    }

    @Override
    public List<AdminDept> listNew() {
        return getBaseMapper().listNew();

    }

    @Override
    public List<Integer> queryDeptByPid(Integer deptId){
        return getBaseMapper().queryDeptByPid(deptId);
    }

    @Override
    public Long queryPidByDeptId(Long deteId) {
        return getBaseMapper().queryPidByDeptId(deteId);
    }

    @Override
    public String queryAllDeptNameByDeptId(Integer deptId){
        LambdaQueryWrapper<AdminDept> queryWrapper = new LambdaQueryWrapper<>();
        List<AdminDept> allDept = this.baseMapper.selectList(queryWrapper);
        AdminDept dept = this.baseMapper.selectById(deptId);
        String name = "";
        if(ObjectUtil.isNotEmpty(dept)){
            name = addParDeptName(name,allDept,dept.getPid());
            if(name.length() > 0){
                name = name.substring(0,name.length() - 1);
            }
            name = name + dept.getName();
        }
        return name;
//        return this.baseMapper.queryAllDeptNameByDeptId(deptId);
    }

    public String addParDeptName(String name,List<AdminDept> allDept ,Integer pid){
        List<AdminDept> pidDeptList = allDept.stream().filter(adminDept -> adminDept.getDeptId().equals(pid)).distinct().collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(pidDeptList)){
            AdminDept pidDept = pidDeptList.stream().findFirst().get();
            if(Integer.valueOf(0).equals(pidDept.getPid())){
                name = pidDept.getName() + "|" + name + "|";
                return name;
            }else{
                name = pidDept.getName() + "|" + name;
                name = addParDeptName(name,allDept,pidDept.getPid());
                return name;
            }
        }
        return "";
    }

    public String queryAllDeptNameByDeptId(Map<Integer,AdminDept> deptMap,Integer deptId){
        AdminDept dept = deptMap.get(deptId);
        if(Optional.ofNullable(dept).isPresent()){
            String deptname = dept.getName();
            deptname = addParDeptName(deptname,deptMap,dept);
            return deptname;
        }
        return StringUtils.EMPTY;
    }


    public String addParDeptName(String name,Map<Integer,AdminDept> deptMap,AdminDept dept){
        AdminDept parent = deptMap.get(dept.getPid());
        if(Optional.ofNullable(parent).isPresent()){
            name = parent.getName() + "|" + name ;
            name = addParDeptName(name,deptMap,parent);
            return name;
        }
        return name;
    }
}
